package com.songlanyun.modules.freighttemplate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.common.validator.group.AddGroup;
import com.songlanyun.common.validator.group.UpdateGroup;
import com.songlanyun.modules.exception.GoodsExceptionEnum;

import com.songlanyun.modules.freighttemplate.entity.FreightTemplate;
import com.songlanyun.modules.freighttemplate.model.dto.FreightTemplateRuleDTO;
import com.songlanyun.modules.freighttemplate.service.FreightTemplateService;
import com.songlanyun.modules.shop.entity.ShopEntity;
import com.songlanyun.modules.shop.service.ShopService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.freighttemplate.dao.FreightTemplateRuleDao;
import com.songlanyun.modules.freighttemplate.entity.FreightTemplateRule;
import com.songlanyun.modules.freighttemplate.service.FreightTemplateRuleService;
import org.springframework.transaction.annotation.Transactional;


@Service("freightTemplateRuleService")
public class FreightTemplateRuleServiceImpl extends ServiceImpl<FreightTemplateRuleDao, FreightTemplateRule> implements FreightTemplateRuleService {

    @Autowired
    private FreightTemplateService freightTemplateService;

    @Autowired
    private ShopService shopService;
    @Override
    public FreightTemplateRule create(FreightTemplateRule entity) {
        ValidatorUtils.validateEntity(entity, AddGroup.class);
        //默认规则只有一条
        validateUnique(entity);
        this.baseMapper.insert(entity);
        return entity;
    }



    @Override
    public FreightTemplateRule modify(FreightTemplateRule entity) {
        ValidatorUtils.validateEntity(entity, UpdateGroup.class);
        //默认规则只有一条
        validateUnique(entity);
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Integer id) {
        this.removeById(id);
    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<FreightTemplateRule> page = this.page(
                new Query<FreightTemplateRule>().getPage(params),
                new QueryWrapper<FreightTemplateRule>()
        );

        return new PageUtils(page);
    }

    /**
     * 为模板创建规则(内部用)
     * @param freightTemplateId
     * @param dto
     * @return
     */
    @Override
    public FreightTemplateRule add(Integer freightTemplateId, FreightTemplateRuleDTO dto) {
        FreightTemplateRule rule = new FreightTemplateRule();
        BeanUtils.copyProperties(dto,rule);

        rule.setFreightComputeMode(OrderConstant.FreightComputeMode.getByCode(dto.getFreightComputeMode()));
        rule.setFreightTemplateId(freightTemplateId);
        this.create(rule);
        return rule;
    }

    /**
     * 修改运费的规则(内部用)
     * @param freightTemplateId
     * @param ruleId
     * @param dto
     * @return
     */
    @Override
    public FreightTemplateRule update(Integer freightTemplateId, Integer ruleId, FreightTemplateRuleDTO dto) {
        FreightTemplateRule rule = this.baseMapper.getByFTidAndRuleId(freightTemplateId,ruleId);
        if(rule==null)
        {
            throw new RRException(GoodsExceptionEnum.FREIGHT_TEMPLATE_RULE_NOT_EXISTS);
        }
        dto.setId(rule.getId());
        if(rule.getGeneral())
        {
            dto.setGeneral(true);
            dto.setAreaRule(new HashMap<>());
        }
        else
        {
            dto.setGeneral(false);
        }
        BeanUtils.copyProperties(dto,rule);

        this.modify(rule);
        return rule;
    }

    /**
     * 删除运费的规则(内部用)
     * @param freightTemplateId
     * @param ruleId
     */
    @Override
    public void delete(Integer freightTemplateId, Integer ruleId) {
        FreightTemplateRule rule = this.baseMapper.getByFTidAndRuleId(freightTemplateId,ruleId);
        if(rule==null)
        {
            //运费规则不存在
            throw new RRException(GoodsExceptionEnum.FREIGHT_TEMPLATE_RULE_NOT_EXISTS);
        }
        if(rule.getGeneral())
        {
            //不能删除默认规则
            throw new RRException(GoodsExceptionEnum.DEFAULT_FREIGHT_TEMPLATE_RULE_NEED);
        }
        this.remove(rule.getId());
    }

    /**
     * 为模板创建规则
     * @param shopId
     * @param templateId
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public FreightTemplateRule createRule(Long shopId, Integer templateId, FreightTemplateRuleDTO dto) {
        ShopEntity shopEntity = shopService.loadShopBy(shopId, true);
        Integer count = this.baseMapper.selectCount(new LambdaQueryWrapper<FreightTemplateRule>()
                .eq(FreightTemplateRule::getFreightTemplateId, templateId));
        if(count>=10)
        {
            throw new RRException(GoodsExceptionEnum.FREIGHT_TEMPLATE_RULE_COUNT);
        }

        FreightTemplate fTemplateBy = freightTemplateService.getFTemplateBy(shopEntity.getId(), templateId);
        if(fTemplateBy==null)
        {
            throw new RRException(GoodsExceptionEnum.FREIGHT_TEMPLATE_NOT_EXISTS);
        }

        dto.setGeneral(false);
        dto.setFreightComputeMode(fTemplateBy.getFreightComputeMode().getCode());
        FreightTemplateRule add = this.add(fTemplateBy.getId(), dto);
        return add;
    }

    /**
     * 修改运费的规则
     * @param shopId
     * @param templateId
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public FreightTemplateRule updateRule(Long shopId, Integer templateId, FreightTemplateRuleDTO dto) {
        ShopEntity shopEntity = shopService.loadShopBy(shopId, true);
        FreightTemplate fTemplateBy = freightTemplateService.getFTemplateBy(shopEntity.getId(), templateId);
        if(fTemplateBy==null)
        {
            throw new RRException(GoodsExceptionEnum.FREIGHT_TEMPLATE_NOT_EXISTS);
        }
        dto.setGeneral(false);
        dto.setFreightComputeMode(fTemplateBy.getFreightComputeMode().getCode());
        return this.update(templateId,dto.getId(),dto);
    }

    /**
     * 删除运费的规则
     * @param shopId
     * @param templateId
     * @param ruleId
     */
    @Override
    @Transactional
    public void deleteRule(Long shopId,Integer templateId, Integer ruleId) {
        this.validateTemplateExist(shopId, templateId);
        this.delete(templateId,ruleId);
    }

    /**
     * 验证模板是否存在
     * @param shopId
     * @param id
     * @return
     */
    private FreightTemplate validateTemplateExist(Long shopId, Integer id)
    {
        FreightTemplate template = this.freightTemplateService.getFTemplateBy(shopId,id);
        if(template==null)
        {
            throw new RRException(GoodsExceptionEnum.FREIGHT_TEMPLATE_NOT_EXISTS);
        }
        return template;
    }

    /**
     * 默认运费模板只有一条
     * @param entity
     */
    private void validateUnique(FreightTemplateRule entity) {
        if(entity.getGeneral())
        {
            LambdaQueryWrapper<FreightTemplateRule> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FreightTemplateRule::getGeneral,true);
            wrapper.eq(FreightTemplateRule::getFreightTemplateId,entity);
            wrapper.last("limit 1");
            FreightTemplateRule defaultFr = this.getOne(wrapper);
            if(defaultFr!=null && !entity.equals(entity))
            {
                throw new RRException(GoodsExceptionEnum.DEFAULT_FREIGHT_TEMPLATE_RULE_UNIQUE);
            }

        }

    }

}